//
//  JJTBaseRequest.m
//  ClaimPlatform_RN
//
//  Created by hamilyjing on 27/03/2018.
//  Copyright © 2018 jj. All rights reserved.
//

#import "JJTBaseRequest.h"

#import "JJTBaseModel.h"
#import "JJNSStringHelper.h"
#import "JJNSMutableDictionaryHelper.h"
#import <YYModel/YYModel.h>
#import "JJTHttpTransportInfoManager.h"
#import "JJTHttpTransportNotification.h"
#import "JJTHttpTransportUrlConfigManager.h"

@implementation JJTBaseRequest

#pragma mark - life cycle

- (instancetype)initWithIdentity:(NSString *)identity_
                      parameters:(NSDictionary *)parameters_
                    isEncryption:(BOOL)isEncryption_
                      modelClass:(Class)modelClass_
                  isSaveToMemory:(BOOL)isSaveToMemory_
                    isSaveToDisk:(BOOL)isSaveToDisk_
{
    self = [super init];
    if (self)
    {
        self.identity = identity_;
        
        BOOL isUserDidOnLine = [JJTHttpTransportInfoManager sharedInstance].isUserDidOnLine;
        if(!isUserDidOnLine)
        {
            NSString *unloginIdentity = [self.identity stringByAppendingString:@"_unlogin"];
            BOOL exist = [[JJTHttpTransportUrlConfigManager sharedInstance] existForIdentity:unloginIdentity];
            if (exist)
            {
                self.identity = unloginIdentity;
            }
        }
        
        self.requestMethodType = YTKRequestMethodPOST;
        self.isSaveToMemory = isSaveToMemory_;
        self.isSaveToDisk = isSaveToDisk_;
        self.modelClass = modelClass_ ? modelClass_ : [JJTBaseModel class];
        
        self.parameters = parameters_;
        self.parametersForSavedFileName = self.parameters;
        
        self.isEncryption = isEncryption_;
        
        // TODO 需要设置区分用户信息
        //self.sensitiveDataForSavedFileName = [JJTHttpTransportInfoManager sharedInstance].regId ?: @"";
        if ([JJTHttpTransportInfoManager sharedInstance].isUserDidOnLine && [JJTHttpTransportInfoManager sharedInstance].userID.length >= 0) {
            self.sensitiveDataForSavedFileName = [JJTHttpTransportInfoManager sharedInstance].userID;
        }
    }
    
    return self;
}

- (instancetype)init
{
    NSAssert(NO, @"Use initWithIdentity:parameters:modelClass:isSaveToMemory:isSaveToDisk: instead of.");
    return nil;
}

#pragma mark - overwrite

- (NSString *)baseUrl
{
    NSString *baseUrl = [[JJTHttpTransportUrlConfigManager sharedInstance] serverHostWithIdentity:self.identity];
    return baseUrl;
}

- (NSString *)requestUrl
{
    NSString *requestUrl = [[JJTHttpTransportUrlConfigManager sharedInstance] serverPathWithIdentity:self.identity];
    return requestUrl;
}

- (id)requestArgument
{
    NSMutableDictionary *dataParameter = [NSMutableDictionary dictionary];
    
    NSDictionary *commonParameter = [self __commonParameter];
    if (commonParameter)
    {
        [dataParameter addEntriesFromDictionary:commonParameter];
    }
    
    if (self.parameters)
    {
        [dataParameter addEntriesFromDictionary:self.parameters];
    }
    
    return dataParameter;
}

- (NSTimeInterval)requestTimeoutInterval
{
    return 30;
}

- (nullable NSDictionary<NSString *, NSString *> *)requestHeaderFieldValueDictionary
{
    return @{@"Accept-Language": @"zh-CN,zh;q=0.8"};
}

- (YTKResponseSerializerType)responseSerializerType {
    return YTKResponseSerializerTypeHTTP;
}

- (void)requestCompleteFilter
{
    [super requestCompleteFilter];
    
    [self processAbnormalStatus];
}

- (id)convertToModel:(NSString *)JSONString_
{
    NSDictionary *responseDic = [JJNSStringHelper dictionaryWithJSON:JSONString_];
    if (![responseDic isKindOfClass:[NSDictionary class]])
    {
        return nil;
    }
    
    NSDictionary *dataDic = [self getConvertModelContent:responseDic];
    
    JJTBaseModel *model;
    if ([dataDic isKindOfClass:[NSDictionary class]])
    {
        model = [[self modelClass] yy_modelWithDictionary:dataDic];
    }
    else if ([dataDic isKindOfClass:[NSArray class]])
    {
        model = [[[self modelClass] alloc] init];
        model.response_dataArray = [NSArray yy_modelArrayWithClass:[self modelClass] json:dataDic];
        if ([model.response_dataArray count] != [dataDic count])
        {
            model.response_dataArray = (NSArray *)dataDic;
        }
    }
    else if ([dataDic isKindOfClass:[NSString class]])
    {
        model = [[[self modelClass] alloc] init];
        model.response_dataString = (NSString *)dataDic;
    }
    else
    {
        model = [[[self modelClass] alloc] init];
    }
    
    [model setBaseModelData:responseDic];
    
    return model;
}

- (BOOL)successForBussiness:(id)model
{
    if ([model isKindOfClass:[JJTBaseModel class]])
    {
        BOOL success = [(JJTBaseModel *)model isValid];
        return success;
    }
    
    return [super successForBussiness:model];
}

#pragma mark - public

+ (id)cacheModelWithIdentity:(NSString *)identity_
                  parameters:(NSDictionary *)parameters_
                isEncryption:(BOOL)isEncryption_
                  modelClass:(Class)modelClass_
{
    return [self cacheModelWithIdentity:identity_
                             parameters:parameters_
                           isEncryption:isEncryption_
                             modelClass:modelClass_
          sensitiveDataForSavedFileName:nil];
}

+ (id)cacheModelWithIdentity:(NSString *)identity_
                  parameters:(NSDictionary *)parameters_
                isEncryption:(BOOL)isEncryption_
                  modelClass:(Class)modelClass_
sensitiveDataForSavedFileName:(NSString *)sensitiveDataForSavedFileName_
{
    JJTBaseRequest *request = [[self alloc] initWithIdentity:identity_ parameters:parameters_ isEncryption:isEncryption_ modelClass:modelClass_ isSaveToMemory:NO isSaveToDisk:NO];
    if (sensitiveDataForSavedFileName_)
    {
        request.sensitiveDataForSavedFileName = sensitiveDataForSavedFileName_;
    }
    id model = [request cacheModel];
    return model;
}

- (id)getConvertModelContent:(NSDictionary *)responseDictionary_
{
    return responseDictionary_;
}

static NSString *g_lastCodeValue = 0;
- (void)processAbnormalStatus
{
    BOOL isUserDidOnLine = [JJTHttpTransportInfoManager sharedInstance].isUserDidOnLine;
    if(!isUserDidOnLine)
    {
        return;
    }
    
    NSDictionary *responseDic = [JJNSStringHelper dictionaryWithJSON:[self filterResponseString:self.responseString]];
    if (![responseDic isKindOfClass:[NSDictionary class]])
    {
        return;
    }
    
    NSString *code = responseDic[@"code"];
    
    static NSString *loginTimeoutCode = @"8979";
    static NSString *otherDeviceLoginedCode = @"5678";
    
    if (([g_lastCodeValue isEqualToString:loginTimeoutCode] || [g_lastCodeValue isEqualToString:otherDeviceLoginedCode])
        && ([code isEqualToString:loginTimeoutCode] || [code isEqualToString:otherDeviceLoginedCode])) {
        return;
    }
    
    g_lastCodeValue = code;
    
    if ([g_lastCodeValue isEqualToString:loginTimeoutCode] || [g_lastCodeValue isEqualToString:otherDeviceLoginedCode])
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:JJTHttpTransportServiceNotificationNameServerForceLogout object:self userInfo:@{JJTHttpTransportServiceNotificationUserInfoKeyCode: code, JJTHttpTransportServiceNotificationUserInfoKeyContent: responseDic ?: @{}}];
    }
}

#pragma mark - private

- (NSDictionary *)__commonParameter
{
    NSMutableDictionary *commonParameters = [NSMutableDictionary dictionary];
    
    NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
    [JJNSMutableDictionaryHelper mDictionary:commonParameters setObj:version forKey:@"appVersion"];
    
    return commonParameters;
}

@end
